package com.tuanzi.loan.business.repository.settlementsystem.impl;

import com.google.common.collect.Lists;
import com.tuanzi.loan.business.entity.settlementsystem.SettlementCompany;
import com.tuanzi.loan.business.repository.settlementsystem.custom.SettlementCompanyRepositoryCustom;
import com.tuanzi.loan.core.repository.JOOQBaseRepositoryPlus;
import com.tuanzi.loan.vo.request.settlementsystem.SettlementCompanyAmountRequest;
import com.tuanzi.loan.vo.request.settlementsystem.SettlementCompanyRequest;
import com.tuanzi.loan.vo.response.settlementsystem.SettlementCompanyResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.jooq.*;
import org.jooq.impl.DSL;
import org.jooq.impl.TableImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import static com.tuanzi.loan.generated.jooq.loan.tables.LoanSettlementCompany.LOAN_SETTLEMENT_COMPANY;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanSettlementIncome.LOAN_SETTLEMENT_INCOME;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanSettlementPrepay.LOAN_SETTLEMENT_PREPAY;

/**
 * @author caiwanlin
 * @create 2018-08-16 16:21
 */
public class SettlementCompanyRepositoryImpl extends JOOQBaseRepositoryPlus implements SettlementCompanyRepositoryCustom {
    @Override
    protected TableImpl getTable() {
        return LOAN_SETTLEMENT_COMPANY;
    }

    @Override
    public Page<SettlementCompanyResponse> list(SettlementCompanyRequest searchRequest, Pageable pageable) {
        Long companyId = searchRequest.getCompanyId();
        String companyName = searchRequest.getCompanyName();
        Integer billType = searchRequest.getBillType();
        String creator = searchRequest.getCreator();
        Date startTime = searchRequest.getStartTime();
        Date endTime = searchRequest.getEndTime();
        if (endTime != null){
            endTime = DateUtils.addHours(endTime, 23);
            endTime = DateUtils.addMinutes(endTime,59);
            endTime = DateUtils.addSeconds(endTime,59);
        }
        fields(LOAN_SETTLEMENT_COMPANY.fields());
        eq(LOAN_SETTLEMENT_COMPANY.ID,companyId);
        contains(LOAN_SETTLEMENT_COMPANY.COMPANY_NAME,companyName);
        eq(LOAN_SETTLEMENT_COMPANY.BILL_TYPE,billType);
        eq(LOAN_SETTLEMENT_COMPANY.CREATOR,creator);
        between(LOAN_SETTLEMENT_COMPANY.CREATE_TIME,startTime,endTime);
        orderBy(LOAN_SETTLEMENT_COMPANY.CREATE_TIME, Sort.Direction.DESC);
        Page<SettlementCompanyResponse> search = search(pageable, record -> {
            SettlementCompanyResponse response = new SettlementCompanyResponse();
            response.setId(record.get(LOAN_SETTLEMENT_COMPANY.ID));
            response.setCompanyName(record.get(LOAN_SETTLEMENT_COMPANY.COMPANY_NAME));
            response.setIsBill(record.get(LOAN_SETTLEMENT_COMPANY.IS_BILL)==null ? 0:record.get(LOAN_SETTLEMENT_COMPANY.IS_BILL).intValue());
            response.setBillContent(record.get(LOAN_SETTLEMENT_COMPANY.BILL_CONTENT));
            response.setTaxNumber(record.get(LOAN_SETTLEMENT_COMPANY.TAX_NUMBER));
            response.setPhone(record.get(LOAN_SETTLEMENT_COMPANY.PHONE));
            response.setBillType(record.get(LOAN_SETTLEMENT_COMPANY.BILL_TYPE));
            response.setBankAddress(record.get(LOAN_SETTLEMENT_COMPANY.BANK_ADDRESS));
            response.setBankAccount(record.get(LOAN_SETTLEMENT_COMPANY.BANK_ACCOUNT));
            response.setBankNumber(record.get(LOAN_SETTLEMENT_COMPANY.BANK_NUMBER));
            response.setReceiveName(record.get(LOAN_SETTLEMENT_COMPANY.RECEIVE_NAME));
            response.setReceivePhone(record.get(LOAN_SETTLEMENT_COMPANY.RECEIVE_PHONE));
            response.setReceiveAddress(record.get(LOAN_SETTLEMENT_COMPANY.RECEIVE_ADDRESS));
            response.setPrepayAmount(record.get(LOAN_SETTLEMENT_COMPANY.PREPAY_AMOUNT));
            response.setExpendAmount(record.get(LOAN_SETTLEMENT_COMPANY.EXPEND_AMOUNT));
            response.setRemark(record.get(LOAN_SETTLEMENT_COMPANY.REMARK));
            response.setCreator(record.get(LOAN_SETTLEMENT_COMPANY.CREATOR));
            response.setCreateTime(record.get(LOAN_SETTLEMENT_COMPANY.CREATE_TIME));
            response.setUpdator(record.get(LOAN_SETTLEMENT_COMPANY.UPDATOR));
            response.setUpdateTime(record.get(LOAN_SETTLEMENT_COMPANY.UPDATE_TIME));
            return response;
        });
        return search;
    }

    @Override
    public Page<SettlementCompanyResponse> listAmount(SettlementCompanyAmountRequest searchRequest, Pageable pageable) {
        Long companyId = searchRequest.getCompanyId();
        Date startTime = searchRequest.getStartTime();
        Date endTime = searchRequest.getEndTime();
        String creator = searchRequest.getCreator();
        List<Condition> conditions = Lists.newArrayList();
        List<Condition> prepayConditions = Lists.newArrayList();
        List<Condition> incomeConditions = Lists.newArrayList();
        if (companyId != null){
            conditions.add(LOAN_SETTLEMENT_COMPANY.ID.eq(companyId));
        }
        if (StringUtils.isNotBlank(creator)){
            conditions.add(LOAN_SETTLEMENT_COMPANY.CREATOR.eq(creator));
        }
        if (startTime != null && endTime != null){
            prepayConditions.add(LOAN_SETTLEMENT_PREPAY.PREPAY_TIME
                    .between(new java.sql.Date(startTime.getTime()),new java.sql.Date(endTime.getTime())));
            incomeConditions.add(LOAN_SETTLEMENT_INCOME.START_TIME
                    .between(new java.sql.Date(startTime.getTime()),new java.sql.Date(endTime.getTime())));
        }
        //收款记录
        SelectHavingStep<Record2<BigDecimal, Long>> subPrepay = dslContext.select(DSL.sum(LOAN_SETTLEMENT_PREPAY.PREPAY_AMOUNT).as("prepayAmount"),
                LOAN_SETTLEMENT_PREPAY.COMPANY_ID)
                .from(LOAN_SETTLEMENT_PREPAY).where(prepayConditions).groupBy(LOAN_SETTLEMENT_PREPAY.COMPANY_ID);
        //消耗记录
        SelectHavingStep<Record2<BigDecimal, Long>> subIncome = dslContext.select(DSL.sum(LOAN_SETTLEMENT_INCOME.INCOME_AMOUNT).as("expendAmount")
                , LOAN_SETTLEMENT_INCOME.COMPANY_ID)
                .from(LOAN_SETTLEMENT_INCOME).where(incomeConditions).groupBy(LOAN_SETTLEMENT_INCOME.COMPANY_ID);


        SelectSeekStep1<? extends Record6<Long, String, String, Timestamp, ?, ?>, Timestamp> record6s = dslContext.select(LOAN_SETTLEMENT_COMPANY.ID, LOAN_SETTLEMENT_COMPANY.COMPANY_NAME,
                LOAN_SETTLEMENT_COMPANY.CREATOR, LOAN_SETTLEMENT_COMPANY.CREATE_TIME,
                subPrepay.field("prepayAmount"), subIncome.field("expendAmount"))
                .from(LOAN_SETTLEMENT_COMPANY)
                .leftJoin(subPrepay).on(LOAN_SETTLEMENT_COMPANY.ID.eq(subPrepay.field(LOAN_SETTLEMENT_PREPAY.COMPANY_ID)))
                .leftJoin(subIncome).on(LOAN_SETTLEMENT_COMPANY.ID.eq(subIncome.field(LOAN_SETTLEMENT_INCOME.COMPANY_ID)))
                .where(conditions).orderBy(LOAN_SETTLEMENT_COMPANY.CREATE_TIME.desc());
        Long count = dslContext.selectCount().from(record6s).fetchOneInto(Long.class);
        List content = record6s.offset(pageable.getOffset()).limit(pageable.getPageSize()).fetchInto(SettlementCompanyResponse.class);
        return new PageImpl<SettlementCompanyResponse>(content, pageable, count == null ? 0 : count);
    }

    @Override
    public List<SettlementCompany> getCompanyList() {
        fields(LOAN_SETTLEMENT_COMPANY.ID,LOAN_SETTLEMENT_COMPANY.COMPANY_NAME);
        List<SettlementCompany> search = search(SettlementCompany.class);
        return search;
    }

    @Override
    public void updateExpendAmount(Long companyId, Double expendAmount) {
        dslContext.update(LOAN_SETTLEMENT_COMPANY)
                .set(LOAN_SETTLEMENT_COMPANY.EXPEND_AMOUNT,expendAmount)
                .where(LOAN_SETTLEMENT_COMPANY.ID.eq(companyId));
    }

    @Override
    public void updatePrepayAmount(Long companyId, Double prepayAmount) {
        dslContext.update(LOAN_SETTLEMENT_COMPANY)
                .set(LOAN_SETTLEMENT_COMPANY.PREPAY_AMOUNT,prepayAmount)
                .where(LOAN_SETTLEMENT_COMPANY.ID.eq(companyId));
    }
}
